package langnstats.project.tools;

/*
 * Author: Wei Chen
 * the logarithm is base e
 */

public class Logdouble {
//	public static double c=Math.log(2);
	public static final double LOG_0 = Double.NEGATIVE_INFINITY;
	
	public static double add(double lp1, double lp2){
		if(lp1==Double.NEGATIVE_INFINITY){ return lp2; }
		if(lp2==Double.NEGATIVE_INFINITY){ return lp1; }
		
		if(lp1>=lp2){
			double diff = lp2-lp1;
			return lp1+Math.log1p(Math.exp(diff));
		}
		else{
			return lp2+Math.log1p(Math.exp(lp1-lp2));
		}
	}
	
	public static double subtract(double lp1, double lp2){
		if(lp2==Double.NEGATIVE_INFINITY){ return lp1; }
		
		if(lp1>lp2){
			return lp1+Math.log(1-Math.exp(lp2-lp1));
		}
		else{
			return Double.NaN;
		}
	}
	
	public static double multiply(double lp1, double lp2){
		return lp1+lp2;
	}
	
	public static double devide(double lp1, double lp2){
		return lp1-lp2;
	}
	
	public static double[] normalizedProb(double[] lpArray){
		double logSum = Double.NEGATIVE_INFINITY;
		for(double logD : lpArray){
			logSum = add(logSum, logD);
		}
		
		double[] normalizedProb = new double[lpArray.length];
		
		for(int i=0; i<normalizedProb.length; i++){
			normalizedProb[i] = Math.pow(Math.E, lpArray[i]-logSum);
		}
		return normalizedProb;
	}
}
